home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / lock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  4.8 KB  |  206 lines

  1. /* 
  2.  * lock.c--
  3.  *
  4.  *    Simple locking functions for Jaquith archive package.
  5.  *
  6.  * Copyright 1992 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "The goal of all inanimate objects is to resist man
  17.  *      and ultimately defeat him."
  18.  *      -- Russell Baker
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/lock.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  23. #endif /* not lint */
  24.  
  25. #include <stdio.h>
  26. #include <sys/file.h>
  27. #include <errno.h>
  28. #include "jaquith.h"
  29.  
  30. extern int jDebug;
  31. extern int syserr;
  32.  
  33. static char printBuf[T_MAXSTRINGLEN];
  34.  
  35. #define LOCKSUFFIX ".LOCK"
  36. #define LOCKFILES "*.LOCK"
  37. #define MAXSLEEPSECS 120      /* arbitrary max timeout value */
  38.  
  39.  
  40. /*
  41.  *----------------------------------------------------------------------
  42.  *
  43.  * Lock_Acquire --
  44.  *
  45.  *    Get exclusive lock on file.
  46.  *
  47.  * Results:
  48.  *    none.
  49.  *
  50.  * Side effects:
  51.  *    Lock file is created with name fileName.LOCK if flock unavailable
  52.  *
  53.  * Note:
  54.  *      The flock routine is not used because it requires that the
  55.  *      processes share a file descriptor.  If the sys admin intervenes,
  56.  *      (restarts a cleaner process that died for example) there's
  57.  *      no way for the newly created process to join the flock crowd.
  58.  *
  59.  *----------------------------------------------------------------------
  60.  */
  61.  
  62. int
  63. Lock_Acquire(fileName, blockFlag, handlePtr)
  64.     char *fileName;           /* name of file to open */
  65.     int blockFlag;            /* if lock is unavailable, return */
  66.     Lock_Handle *handlePtr;   /* receiving structure */
  67. {
  68.     int retCode = T_FAILURE;
  69.     static char pidChar[12];
  70.     static int pidLen = 0;
  71.     int mode = O_RDWR+O_CREAT+O_EXCL;
  72.     int sleepSecs = 1;
  73.  
  74.     strcpy(handlePtr->lockName, fileName);
  75.     strcat(handlePtr->lockName, LOCKSUFFIX);
  76.  
  77.     handlePtr->lockFd = open(handlePtr->lockName, mode, 0600);
  78.  
  79.     if ((handlePtr->lockFd == -1) && (blockFlag == LOCK_BLOCK)) {
  80.     while (errno == EEXIST) {
  81.         sleep(sleepSecs);
  82.         if (sleepSecs < MAXSLEEPSECS) {
  83.         sleepSecs *= 2;
  84.         }
  85.         if ((handlePtr->lockFd=open(handlePtr->lockName, mode, 0600))
  86.         != -1) {
  87.         break;
  88.         }
  89.     }
  90.     }
  91.  
  92.     if (handlePtr->lockFd != -1) {
  93.     retCode = T_SUCCESS;
  94.     if (pidLen == 0) {
  95.         sprintf(pidChar, "0x%x\n\0", getpid());
  96.         pidLen = strlen(pidChar);
  97.     }
  98.     write(handlePtr->lockFd, pidChar, pidLen);
  99.     }
  100. /*
  101.     if (jDebug) {
  102.     fprintf(stderr,"Lock_Acquire: %s: retcode %d\n",
  103.         handlePtr->lockName, retCode);
  104.     }
  105. */
  106.     return retCode;
  107.  
  108. }
  109.  
  110.  
  111. /*
  112.  *----------------------------------------------------------------------
  113.  *
  114.  * Lock_Release --
  115.  *
  116.  *    Release exclusive lock on file
  117.  *
  118.  * Results:
  119.  *    none.
  120.  *
  121.  * Side effects:
  122.  *    removes lock file, if not using flock.
  123.  *
  124.  *----------------------------------------------------------------------
  125.  */
  126.  
  127. int
  128. Lock_Release(handlePtr)
  129.     Lock_Handle *handlePtr;   /* item to release */
  130. {
  131. /*
  132.     if (jDebug) {
  133.     fprintf(stderr,"Lock_Release: %s\n", handlePtr->lockName);
  134.     }
  135. */
  136.     if (close(handlePtr->lockFd) == -1) {
  137.     syserr = errno;
  138.     fprintf(stderr, "Lock_Release: close failed on %s. errno %d\n",
  139.         handlePtr->lockName, syserr);
  140.     }
  141.  
  142.     if (unlink(handlePtr->lockName) == -1) {
  143.     syserr = errno;
  144.     fprintf(stderr, "Lock_Release: unlink failed on %s. errno %d\n",
  145.         handlePtr->lockName, syserr);
  146.     }
  147.  
  148.     return T_SUCCESS;
  149. }
  150.  
  151.  
  152.  
  153. /*
  154.  *----------------------------------------------------------------------
  155.  *
  156.  * Lock_RemoveAll --
  157.  *
  158.  *    Remove all lock files in directory.
  159.  *
  160.  * Results:
  161.  *    none.
  162.  *
  163.  * Side effects:
  164.  *    Lock file is (conditionally) removed.
  165.  *
  166.  *----------------------------------------------------------------------
  167.  */
  168.  
  169. void
  170. Lock_RemoveAll(dirPath, confirmFlag)
  171.     char *dirPath;            /* directory to clean */
  172.     int confirmFlag;          /* 1 == request confirmation */
  173. {
  174.     DIR *dirPtr;
  175.     DirObject *entryPtr;
  176.     struct stat unixStatBuf;
  177.     char pathName[T_MAXPATHLEN];
  178.     char answer[T_MAXLINELEN];
  179.  
  180.     *answer = 'y';
  181.  
  182.     if ((dirPtr=(DIR *)opendir(dirPath)) == (DIR *) NULL) {
  183.     return;
  184.     }
  185.  
  186.     while ((entryPtr=readdir(dirPtr)) != (DirObject *)NULL) {
  187.     if (Str_Match(entryPtr->d_name, LOCKFILES)) {
  188.         strcpy(pathName, dirPath);
  189.         strcat(pathName, "/");
  190.         strcat(pathName, entryPtr->d_name);
  191.         stat(pathName, &unixStatBuf);
  192.         if (S_ISREG(unixStatBuf.st_mode)) {
  193.         if (confirmFlag) {
  194.             sprintf(printBuf,"Delete old lock file: %s ? ", pathName);
  195.             if (Utils_GetOk(printBuf)) {
  196.             unlink(pathName);
  197.             }
  198.         }
  199.         }
  200.     }
  201.     }
  202.  
  203.     closedir(dirPtr);
  204. }
  205.  
  206.